//! 事件系统核心定义
//! 
//! 提供通用的事件类型、优先级系统和处理器接口

// use std::sync::Arc;  // 已注释：未使用的导入
use std::time::{SystemTime, UNIX_EPOCH};
use std::fmt;
use serde::{Serialize, Deserialize};

// =============================================================================
// 类型别名（简化复杂类型定义）
// =============================================================================

/// 常用的处理器映射类型
pub type HandlerMap = fxhash::FxHashMap<String, Vec<std::sync::Arc<dyn DynamicEventHandler>>>;

/// 线程安全的处理器映射
pub type SafeHandlerMap = std::sync::Arc<std::sync::RwLock<HandlerMap>>;

/// 事件队列类型
pub type EventQueue<T> = std::sync::Arc<crate::core::concurrency::LockFreeMPMCQueue<T>>;

/// 线程安全的原子布尔
pub type SafeAtomicBool = std::sync::Arc<std::sync::atomic::AtomicBool>;

/// 线程安全的原子计数器
pub type SafeAtomicU64 = std::sync::Arc<std::sync::atomic::AtomicU64>;

/// 事件处理器引用
pub type EventHandlerRef = std::sync::Arc<dyn DynamicEventHandler>;

/// 线程安全的处理器列表
pub type SafeHandlerList = std::sync::Arc<std::sync::RwLock<Vec<EventHandlerRef>>>;

/// 统计数据类型
pub type StatsMap = fxhash::FxHashMap<String, u64>;

/// 常用的结果类型
pub type EventBoxResult<T> = Result<T, Box<str>>;

/// 常用的事件发送结果
pub type EventSendResult = Result<(), DynamicEvent>;

/// 事件唯一标识符
pub type EventId = u64;

/// 事件类型标识
pub type EventType = &'static str;

/// 事件优先级
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[derive(Default)]
pub enum Priority {
    /// 低优先级 - 可延迟处理的事件
    Low = 1,
    /// 普通优先级 - 常规业务事件
    #[default]
    Normal = 2,
    /// 高优先级 - 重要业务事件
    High = 3,
    /// 紧急优先级 - 需要立即处理的事件
    Critical = 4,
}


impl fmt::Display for Priority {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Priority::Low => write!(f, "LOW"),
            Priority::Normal => write!(f, "NORMAL"), 
            Priority::High => write!(f, "HIGH"),
            Priority::Critical => write!(f, "CRITICAL"),
        }
    }
}

/// 事件元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventMetadata {
    /// 事件ID
    pub id: EventId,
    /// 事件类型
    pub event_type: String,
    /// 创建时间戳（毫秒）
    pub timestamp: u64,
    /// 事件优先级
    pub priority: Priority,
    /// 事件来源（可选）
    pub source: Option<String>,
    /// 关联ID（用于事件链追踪）
    pub correlation_id: Option<String>,
    /// 自定义属性
    pub attributes: fxhash::FxHashMap<String, String>,
}

impl EventMetadata {
    /// 创建新的事件元数据
    pub fn new(event_type: impl Into<String>) -> Self {
        Self {
            id: generate_event_id(),
            event_type: event_type.into(),
            timestamp: current_timestamp_millis(),
            priority: Priority::default(),
            source: None,
            correlation_id: None,
            attributes: fxhash::FxHashMap::default(),
        }
    }

    /// 设置优先级
    pub fn with_priority(mut self, priority: Priority) -> Self {
        self.priority = priority;
        self
    }

    /// 设置来源
    pub fn with_source(mut self, source: impl Into<String>) -> Self {
        self.source = Some(source.into());
        self
    }

    /// 设置关联ID
    pub fn with_correlation_id(mut self, correlation_id: impl Into<String>) -> Self {
        self.correlation_id = Some(correlation_id.into());
        self
    }

    /// 添加属性
    pub fn with_attribute(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
        self.attributes.insert(key.into(), value.into());
        self
    }

    /// 获取事件年龄（毫秒）
    pub fn age_millis(&self) -> u64 {
        current_timestamp_millis().saturating_sub(self.timestamp)
    }
}

/// 事件负载数据（泛型）
pub trait EventPayload: Send + Sync + std::fmt::Debug {
    /// 获取负载类型名称
    fn payload_type(&self) -> &'static str;
    
    /// 序列化负载为字节数组（用于持久化或网络传输）
    fn serialize(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>>;
    
    /// 获取负载大小（字节）
    fn size(&self) -> usize;
}

// 为Box<dyn EventPayload>实现EventPayload trait
impl EventPayload for Box<dyn EventPayload> {
    fn payload_type(&self) -> &'static str {
        (**self).payload_type()
    }
    
    fn serialize(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
        (**self).serialize()
    }
    
    fn size(&self) -> usize {
        (**self).size()
    }
}

/// 通用事件结构（优化内存布局）
#[derive(Debug)]
pub struct Event<T: EventPayload> {
    /// 事件元数据（装箱以减少栈上大小）
    pub metadata: Box<EventMetadata>,
    /// 事件负载
    pub payload: T,
}

impl<T: EventPayload> Event<T> {
    /// 创建新事件
    pub fn new(event_type: impl Into<String>, payload: T) -> Self {
        Self {
            metadata: Box::new(EventMetadata::new(event_type)),
            payload,
        }
    }

    /// 使用指定元数据创建事件
    pub fn with_metadata(metadata: EventMetadata, payload: T) -> Self {
        Self {
            metadata: Box::new(metadata),
            payload,
        }
    }

    /// 获取事件ID
    pub fn id(&self) -> EventId {
        self.metadata.id
    }

    /// 获取事件类型
    pub fn event_type(&self) -> &str {
        &self.metadata.event_type
    }

    /// 获取优先级
    pub fn priority(&self) -> Priority {
        self.metadata.priority
    }

    /// 获取时间戳
    pub fn timestamp(&self) -> u64 {
        self.metadata.timestamp
    }

    /// 获取事件总大小（元数据 + 负载）
    pub fn total_size(&self) -> usize {
        // 简化计算：元数据大小 + 负载大小
        std::mem::size_of::<Box<EventMetadata>>() + self.payload.size()
    }
}

/// 动态事件（支持运行时类型）
pub type DynamicEvent = Event<Box<dyn EventPayload>>;

/// 事件处理结果（优化内存布局）
#[derive(Debug, Clone, PartialEq)]
pub enum EventResult {
    /// 处理成功
    Success,
    /// 处理失败，包含错误信息（装箱以减少大小）
    Failed(Box<str>),
    /// 跳过处理
    Skipped,
    /// 需要重试
    Retry(u32), // 重试次数
}

impl EventResult {
    /// 创建失败结果
    pub fn failed(msg: impl Into<String>) -> Self {
        EventResult::Failed(msg.into().into_boxed_str())
    }
    
    /// 检查是否成功
    pub fn is_success(&self) -> bool {
        matches!(self, EventResult::Success)
    }

    /// 检查是否失败
    pub fn is_failed(&self) -> bool {
        matches!(self, EventResult::Failed(_))
    }

    /// 检查是否需要重试
    pub fn should_retry(&self) -> bool {
        matches!(self, EventResult::Retry(_))
    }

    /// 获取错误信息（如果有）
    pub fn error_message(&self) -> Option<&str> {
        match self {
            EventResult::Failed(msg) => Some(msg),
            _ => None,
        }
    }
}

impl fmt::Display for EventResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            EventResult::Success => write!(f, "SUCCESS"),
            EventResult::Failed(msg) => write!(f, "FAILED: {msg}"),
            EventResult::Skipped => write!(f, "SKIPPED"),
            EventResult::Retry(count) => write!(f, "RETRY({count})"),
        }
    }
}

/// 事件处理器接口
pub trait EventHandler<T: EventPayload>: Send + Sync {
    /// 处理事件
    fn handle(&self, event: &Event<T>) -> EventResult;
    
    /// 获取处理器名称
    fn name(&self) -> &str;
    
    /// 检查是否能处理指定类型的事件
    fn can_handle(&self, event_type: &str) -> bool;
    
    /// 获取处理器优先级（用于处理器排序）
    fn handler_priority(&self) -> i32 {
        0
    }
}

/// 动态事件处理器（支持运行时类型）
pub trait DynamicEventHandler: Send + Sync {
    /// 处理动态事件
    fn handle_dynamic(&self, event: &DynamicEvent) -> EventResult;
    
    /// 获取处理器名称
    fn name(&self) -> &str;
    
    /// 检查是否能处理指定类型的事件
    fn can_handle(&self, event_type: &str) -> bool;
    
    /// 获取处理器优先级
    fn handler_priority(&self) -> i32 {
        0
    }
}

/// 事件处理上下文
#[derive(Debug)]
pub struct EventContext {
    /// 处理开始时间
    pub start_time: u64,
    /// 重试次数
    pub retry_count: u32,
    /// 上下文属性
    pub context_data: fxhash::FxHashMap<String, String>,
}

impl EventContext {
    /// 创建新的处理上下文
    pub fn new() -> Self {
        Self {
            start_time: current_timestamp_millis(),
            retry_count: 0,
            context_data: fxhash::FxHashMap::default(),
        }
    }

    /// 增加重试次数
    pub fn increment_retry(&mut self) {
        self.retry_count += 1;
    }

    /// 获取处理时间（毫秒）
    pub fn processing_time_millis(&self) -> u64 {
        current_timestamp_millis().saturating_sub(self.start_time)
    }

    /// 添加上下文数据
    pub fn add_data(&mut self, key: impl Into<String>, value: impl Into<String>) {
        self.context_data.insert(key.into(), value.into());
    }
}

impl Default for EventContext {
    fn default() -> Self {
        Self::new()
    }
}

/// 事件批处理
#[derive(Debug)]
pub struct EventBatch<T: EventPayload> {
    /// 批次ID
    pub batch_id: String,
    /// 批次中的事件
    pub events: Vec<Event<T>>,
    /// 批次创建时间
    pub created_at: u64,
    /// 批次大小限制
    pub max_size: usize,
}

impl<T: EventPayload> EventBatch<T> {
    /// 创建新的事件批次
    pub fn new(batch_id: impl Into<String>, max_size: usize) -> Self {
        Self {
            batch_id: batch_id.into(),
            events: Vec::with_capacity(max_size),
            created_at: current_timestamp_millis(),
            max_size,
        }
    }

    /// 添加事件到批次
    pub fn add_event(&mut self, event: Event<T>) -> Result<(), Event<T>> {
        if self.events.len() >= self.max_size {
            Err(event)
        } else {
            self.events.push(event);
            Ok(())
        }
    }

    /// 检查批次是否已满
    pub fn is_full(&self) -> bool {
        self.events.len() >= self.max_size
    }

    /// 检查批次是否为空
    pub fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    /// 获取批次大小
    pub fn len(&self) -> usize {
        self.events.len()
    }

    /// 获取批次总数据大小
    pub fn total_size(&self) -> usize {
        self.events.iter().map(|e| e.total_size()).sum()
    }

    /// 清空批次
    pub fn clear(&mut self) {
        self.events.clear();
    }
}

// 辅助函数

/// 生成唯一事件ID
fn generate_event_id() -> EventId {
    use std::sync::atomic::{AtomicU64, Ordering};
    static COUNTER: AtomicU64 = AtomicU64::new(0);
    
    let timestamp = current_timestamp_millis();
    let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
    
    // 组合时间戳和计数器生成唯一ID
    (timestamp << 20) | (counter & 0xFFFFF)
}

/// 获取当前时间戳（毫秒）
fn current_timestamp_millis() -> u64 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_millis() as u64
}

// 常用事件负载实现

/// 字符串负载
#[derive(Debug, Clone)]
pub struct StringPayload(pub String);

impl EventPayload for StringPayload {
    fn payload_type(&self) -> &'static str {
        "string"
    }

    fn serialize(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
        Ok(self.0.as_bytes().to_vec())
    }

    fn size(&self) -> usize {
        self.0.len()
    }
}

/// JSON负载
#[derive(Debug, Clone)]
pub struct JsonPayload(pub serde_json::Value);

impl EventPayload for JsonPayload {
    fn payload_type(&self) -> &'static str {
        "json"
    }

    fn serialize(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
        serde_json::to_vec(&self.0).map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
    }

    fn size(&self) -> usize {
        self.serialize().map(|v| v.len()).unwrap_or(0)
    }
}

/// 二进制负载
#[derive(Debug, Clone)]
pub struct BinaryPayload(pub Vec<u8>);

impl EventPayload for BinaryPayload {
    fn payload_type(&self) -> &'static str {
        "binary"
    }

    fn serialize(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
        Ok(self.0.clone())
    }

    fn size(&self) -> usize {
        self.0.len()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_event_metadata() {
        let metadata = EventMetadata::new("test_event")
            .with_priority(Priority::High)
            .with_source("test_source")
            .with_correlation_id("test_correlation")
            .with_attribute("key1", "value1");

        assert_eq!(metadata.event_type, "test_event");
        assert_eq!(metadata.priority, Priority::High);
        assert_eq!(metadata.source, Some("test_source".to_string()));
        assert_eq!(metadata.correlation_id, Some("test_correlation".to_string()));
        assert_eq!(metadata.attributes.get("key1"), Some(&"value1".to_string()));
    }

    #[test]
    fn test_event_creation() {
        let payload = StringPayload("test message".to_string());
        let event = Event::new("message", payload);

        assert_eq!(event.event_type(), "message");
        assert_eq!(event.priority(), Priority::Normal);
        assert!(event.id() > 0);
        assert!(event.timestamp() > 0);
    }

    #[test]
    fn test_event_result() {
        assert!(EventResult::Success.is_success());
        assert!(!EventResult::Success.is_failed());
        assert!(!EventResult::Success.should_retry());

        let failed = EventResult::failed("error");
        assert!(!failed.is_success());
        assert!(failed.is_failed());
        assert_eq!(failed.error_message(), Some("error"));

        let retry = EventResult::Retry(3);
        assert!(retry.should_retry());
        assert!(!retry.is_success());
    }

    #[test]
    fn test_event_batch() {
        let mut batch = EventBatch::new("test_batch", 2);
        assert!(batch.is_empty());
        assert!(!batch.is_full());

        let event1 = Event::new("test", StringPayload("msg1".to_string()));
        let event2 = Event::new("test", StringPayload("msg2".to_string()));
        let event3 = Event::new("test", StringPayload("msg3".to_string()));

        assert!(batch.add_event(event1).is_ok());
        assert!(batch.add_event(event2).is_ok());
        assert!(batch.is_full());

        // 应该失败，因为批次已满
        assert!(batch.add_event(event3).is_err());
        assert_eq!(batch.len(), 2);
    }

    #[test]
    fn test_priority_ordering() {
        assert!(Priority::Critical > Priority::High);
        assert!(Priority::High > Priority::Normal);
        assert!(Priority::Normal > Priority::Low);
    }

    #[test]
    fn test_payload_implementations() {
        let string_payload = StringPayload("hello".to_string());
        assert_eq!(string_payload.payload_type(), "string");
        assert_eq!(string_payload.size(), 5);

        let json_payload = JsonPayload(serde_json::json!({"key": "value"}));
        assert_eq!(json_payload.payload_type(), "json");
        assert!(json_payload.size() > 0);

        let binary_payload = BinaryPayload(vec![1, 2, 3, 4]);
        assert_eq!(binary_payload.payload_type(), "binary");
        assert_eq!(binary_payload.size(), 4);
    }
}